package com.uy.system.service.impl;

import com.uy.system.common.constant.SystemConstants;
import com.uy.system.common.utils.SessionUtils;
import com.uy.system.distribute.DistributedCacheService;
import com.uy.system.model.entity.SysMenu;
import com.uy.system.mapper.SysMenuMapper;
import com.uy.system.model.vo.SysMenuTreeVO;
import com.uy.system.service.ISysMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.uy.system.utils.BeanUtils;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 菜单权限表 服务实现类
 * </p>
 *
 * @author ly
 * @since 2024-03-22
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {

    @Resource
    private DistributedCacheService distributedCacheService;

    @Override
    public List<SysMenuTreeVO> menuTree() {
        List<SysMenu> menus = baseMapper.getMenusByUserId(Long.valueOf(SessionUtils.getUserId()));
        return tree(menus, 0L);
    }

    @Override
    public List<String> getPermissionList(Long userId) {
        List<String> permissionList = baseMapper.getPermissionList(userId);
        String key = SystemConstants.SYS_USER_MENU_PERMI_KEY + userId;
        distributedCacheService.set(key, permissionList, SystemConstants.CACHE_TIME, TimeUnit.SECONDS);
        return permissionList;
    }

    /**
     * 菜单树
     * @param menus 菜单数据
     * @param root 根节点
     * @return 树型数据
     */
    private List<SysMenuTreeVO> tree(List<SysMenu> menus, Long root){
        Map<Long, List<SysMenuTreeVO>> parentMap = new HashMap<>();
        List<SysMenuTreeVO> list = new ArrayList<>();
        List<SysMenuTreeVO> trees = new ArrayList<>();
        for (SysMenu sm: menus){
            SysMenuTreeVO vo = BeanUtils.copyProperties(sm, SysMenuTreeVO.class);
            list.add(vo);
            Long parentId = vo.getParentId();
            if (parentId == root){
                trees.add(vo);
                continue;
            }
            parentMap.computeIfAbsent(parentId, key -> new ArrayList<>()).add(vo);
        }
        for (SysMenuTreeVO menu: list){
            menu.setChildren(parentMap.get(menu.getMenuId()));
        }
        return trees;
    }
}
